﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace PointerPlayground
{
    public class Program
    {
        public unsafe static void Main(string[] arags)
        {
            //结构体
            //显示CurrencyStruct的字节数，创建他的对象和指针
            Console.WriteLine("CurrencyStruct ByteSize:" + sizeof(CurrencyStruct));
            Console.WriteLine("CurrencyStruct* ByteSize:" + sizeof(CurrencyStruct*));
            Console.WriteLine("long* ByteSize:" + sizeof(long));
            Console.WriteLine("int* ByteSize:" + sizeof(int));
            Console.WriteLine("short* ByteSize:" + sizeof(short));
            CurrencyStruct amount1, amount2;
            CurrencyStruct* pA1 = &amount1;
            long* pYuan1 = &(pA1->Yuan);
            short* pJiao1 = &(pA1->Jiao);

            Console.WriteLine(@"CurrencyStruct amount1 Address:{0}", (ulong)&amount1);
            Console.WriteLine(@"CurrencyStruct amount2 Address:{0}", (ulong)&amount2);
            Console.WriteLine(@"CurrencyStruct pA1 Address:{0}", (ulong)&pA1);
            Console.WriteLine(@"CurrencyStruct pYuan1 Address:{0}", (ulong)&pYuan1);
            Console.WriteLine(@"CurrencyStruct pJiao1 Address:{0}", (ulong)&pJiao1);


            pA1->Yuan = 20;
            *pJiao1 = 10;
            Console.WriteLine("Money:{0}", pA1->ToString());


            --pA1;
            Console.WriteLine(@"CurrencyStruct pA1-- Address:{0},Data:{1}", (ulong)pA1, pA1->ToString());

            //使用指针将pJiao1指向amount2.Jiao

            Console.WriteLine(@"CurrencyStruct pJiao1 now Address:{0},Data:{1}", (ulong)&pJiao1, (ulong)pJiao1);
            //CurrencyStruct* pTempA1 = (CurrencyStruct*)pJiao1;
            //pJiao1 = (short*)(--pTempA1);
            pJiao1 -= (sizeof(CurrencyStruct) / sizeof(short));
            *pJiao1 = 996;
            Console.WriteLine(@"CurrencyStruct pJiao1 change now Address:{0},Data:{1}", (ulong)&pJiao1, (ulong)pJiao1);
            Console.WriteLine(@"CurrencyStruct amount2.Jiao now Address:{0},Data:{1}", (ulong)&(amount2.Jiao), amount2.ToString());


            //类成员指针跳跃
            CurrencyClass currency1 = new CurrencyClass();
            CurrencyClass currency2 = new CurrencyClass();
            Console.WriteLine(@"CurrencyClass ByteSize:" + Marshal.SizeOf(currency2));
            fixed (long* pC1Yuan = &currency1.Yuan, pC2Yuan = &currency2.Yuan)
            fixed (short* pC1Jiao = &currency1.Jiao, pC2Jiao = &currency2.Jiao)
            {
                Console.WriteLine(@"CurrencyClass currency1.pC1Yuan Address:{0}", (ulong)pC1Yuan);
                Console.WriteLine(@"CurrencyClass currency1.pC1Jiao Address:{0}", (ulong)pC1Jiao);
                Console.WriteLine(@"CurrencyClass currency2.pC2Yuan Address:{0}", (ulong)pC2Yuan);
                Console.WriteLine(@"CurrencyClass currency2.pC2Jiao Address:{0}", (ulong)pC2Jiao);

                long* pYuanTemp = pC1Yuan + ((16 + Marshal.SizeOf<CurrencyClass>()) / sizeof(long));
                *pYuanTemp = 007;

                *(pC1Yuan + 1) = 100;

                Console.WriteLine(@"CurrencyClass currency1.pC1Yuan jump to currency2 Address:{0},Data:{1}", (ulong)pYuanTemp, pYuanTemp->ToString());
                Console.WriteLine(@"CurrencyClass currency1.pC1Yuan jump to currency1.Jiao Address:{0},Data:{1}", (ulong)(pC1Yuan + 1), (pC1Yuan + 1)->ToString());
                Console.WriteLine(@"CurrencyClass currency1 Data:{0}", currency1);
                Console.WriteLine(@"CurrencyClass currency2 Data:{0}", currency2);

            }
        }
    }
}
